//////////////////////////////////////////////////////////////////////////////////
//	Copyright 2011 by Yosef Grabivker, ryuho@homenetworksoft.com
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
//////////////////////////////////////////////////////////////////////////////////

#include <wx/wx.h>
#include "mainwnd.h"
#include "linktorouter.h"
#include "telnetlink.h"
#include "logicmanager.h"
#include "locallink.h"

CLinkToRouter::CLinkToRouter(CMainWnd& wnd):
	wxThread(wxTHREAD_JOINABLE), m_wMain(wnd), m_bThreadRun(false)
{
	memset(m_log, 0, sizeof(m_log));
}

CLinkToRouter::~CLinkToRouter()
{
	//OutputDebugStr(_T("CLinkToRouter::~CLinkToRouter()\n"));
	DestroyLink();
}

void CLinkToRouter::CreateLink(const CONPARAMS& params)
{
	m_params = params;

	if ( wxTHREAD_NO_ERROR !=Create() ) THROW_EXC(cERFailed);

	SetPriority(WXTHREAD_MIN_PRIORITY);
		
	if ( wxTHREAD_NO_ERROR !=Run() ) THROW_EXC(cERFailed);
}

void CLinkToRouter::TerminateThread()
{
	//OutputDebugStr(_T("CLinkToRouter::TerminateThread() Begin\n"));
	DestroyLink();
	//OutputDebugStr(_T("CLinkToRouter::TerminateThread() End\n"));
}

void CLinkToRouter::DestroyLink()
{
	//OutputDebugStr(_T("CLinkToRouter::DestroyLink() Begin\n"));

	if ( IsAlive() )
	{
		COMMANDREQUEST cmd;
		cmd.code = cCmdQuit;
		AddRequest(cmd);

		int n=100;

		while( m_bThreadRun && n-->0 )
		{
			Sleep(100);
		}
		
		//OutputDebugStr(_T("CLinkToRouter::DestroyLink() Delete\n"));
		Delete();
	}

	//OutputDebugStr(_T("CLinkToRouter::DestroyLink() End\n"));
}

void* CLinkToRouter::Entry()
{
	//OutputDebugStr(_T("CLinkToRouter::Entry() Begin()\n"));

	void* pRet(NULL);

	m_bThreadRun = true;
	
	/*
	CLinkGuard 	   link(
			#ifdef LINUX
			new CLocalLink
			#else
			new CTelnetLink
			#endif
			);
	*/
	
	CLinkGuard 	   link( new CTelnetLink );
	CLogicManager  logic(link, *this, m_wMain);
	cExcReason	   excReason = cERNone;

	if ( link )
	{
		try
		{
			link->Connect( m_params );

			std::string strModemSet, strWirelessSet;

			strModemSet = (const char*)m_params.strModemSettings.ToAscii();
			strWirelessSet = (const char*)m_params.strWirelessSettings.ToAscii();
			
			logic.Init( strModemSet, strWirelessSet );
						
			while( true )
			{
				if ( TestDestroy() )
					break;
				
				if ( !logic.Tick() )
					break;
				
				int i=10;
				while(i-->0)
				{
					if ( TestDestroy() )
						break;

					Sleep(TICK_TIME/10);
				}
			}
		}
		catch( CRTException& exc )
		{
			//logic.ReportThreadErrorExit( exc.GetReason() );
			excReason = exc.GetReason();
		}
		catch( ... )
		{
			excReason = cEROtherException;
			//logic.ReportThreadErrorExit( excReason );
		}

		strncpy( m_log, link->GetLog().c_str(), sizeof(m_log)-1);
	}
	
	logic.ReportThreadExit(excReason);

	//OutputDebugStr(_T("CLinkToRouter::Entry() End()\n"));

	m_bThreadRun = false;

	return pRet;
}